Spark SQL 3.0 性能提升概览

归纳为4类:开发交互、动态优化、Catalyst提升和框架更新

1 新的EXPLAIN格式

更加简洁清晰的执行计划展示。首行为操作符,次行为属性集合,通过id关联。

截屏2020-12-24 上午9.06.26

2 所有的关联类型提示

更加丰富的关联提示,用于提示catalyst行为。

截屏2020-12-24 上午9.13.27

3 自适应查询执行

使用运行时统计信息,主要优化参数:

  • 调整reducer数量,用于减少资源浪费

    版本2.4通过spark.sql.suffle partitions(默认:200)固定分配,导致reducer间工作负载不均。

    版本3.0通过调整reducer数量达到负载均衡。默认关闭。

    spark.sql.adaptive.enabled

    spark.sql.adaptive.coalescePartitions.enabled

  • 关联策略,用于提升性能

    版本2.4通过表大小等统计信息选择关联策略,但是存在着中间结果(如中间表)信息在查询优化时不可用的情形。

    版本3.0通过运行时信息选择,可以察觉中间结果信息。需要开启spark.sql.adaptive.enabled

  • 调整分区数量,优化倾斜关联,避免工作负载不均

    版本2.4执行时间取决于最大的分区

    版本3.0可以自动切割较大分区。默认关闭

    spark.sql.adaptive.enabled

    spark.sql.adaptive.skewJoin.enabled

截屏2020-12-24 上午9.35.49

4 动态分区裁剪

使用谓词下推避免读取不必要的分区。如大小表Broadcast Hash Join。

版本2.4中,大表无法使用小表的过滤条件。

版本3.0可以使用带有动态过滤的下推,减少读取大表的数据量

截屏2020-12-25 上午9.17.57

截屏2020-12-25 上午9.33.07

上图中在分区过滤阶段使用了动态分区裁剪。

5 加强的列裁剪和下推

列裁剪可用于提升嵌套列操作效率,通常用于LIMIT等操作。

版本2.4使用临时查询(ad hoc)实现。不是作为算子执行,先读取大多数列,再重分区,之后再裁减。如图列2

版本3.0可以应用列裁剪到所有的操作中。在一开始就应用了列裁剪。如图列1

截屏2020-12-25 上午9.57.45

截屏2020-12-25 上午10.04.02

版本2.4不支持嵌套列谓词下推,版本3.0支持。

截屏2020-12-25 上午10.19.07

6 聚合代码更新

在Spark中,通常Catalyst被翻译为Java代码。但是当代码量太大时,HotSpot将放弃将代码转换为本地代码,导致性能不理想,如聚合代码。

版本3.0拆分复杂代码为较小的方法,从而实现到本地代码的转换。

截屏2020-12-27 上午9.01.24

截屏2020-12-27 上午9.01.59

上图上侧为开启聚合更新的Spark代码和行数,下方为关闭后的情形。

7 新的Scala和Java

版本3.0支持新的语言版本Java 11和Scala 2.12。

Java 11是长期支持版本,到2026。在native coordination和垃圾收集上大幅提升。

截屏2020-12-27 上午9.07.50

参考资料

SQL Performance Improvements at a Glance in Apache Spark 3.0

截屏2020-12-27 上午9.09.35

截屏2020-12-27 上午9.09.35